import asyncio
from tenacity import retry, stop_after_attempt, wait_fixed
from web.configs.config import settings
from web.utils.redis_utils import RedisClient
from web.services.callback_service import send_callback
from loguru import logger

async def process_pdf_task(task_data: dict):
    doc_id = task_data["doc_id"]
    callback_url = task_data.get("callback_url")

    if await RedisClient().is_processed(doc_id):
        logger.info(f"Skipping already processed doc_id: {doc_id}")
        return

    try:
        await RedisClient().mark_as_processing(doc_id)

        pdf_content = await download_pdf(doc_id)
        markdown_content = await convert_pdf_to_markdown(pdf_content)
        await store_result(doc_id, markdown_content)

        if callback_url:
            await send_callback(callback_url, {
                "status": "completed",
                "doc_id": doc_id,
                "message": "PDF processing completed successfully"
            })

        await RedisClient().mark_as_processed(doc_id)
    except Exception as e:
        logger.error(f"Failed to process PDF {doc_id}: {str(e)}")
        if callback_url:
            await send_callback(callback_url, {
                "status": "failed",
                "doc_id": doc_id,
                "error": str(e)
            })
        raise

@retry(stop=stop_after_attempt(settings.retry_max_attempts), wait=wait_fixed(settings.retry_wait_fixed))
async def download_pdf(doc_id: str) -> bytes:
    await asyncio.sleep(1)  # Simulate network delay
    return b"PDF_CONTENT_SIMULATION"

@retry(stop=stop_after_attempt(settings.retry_max_attempts), wait=wait_fixed(settings.retry_wait_fixed))
async def convert_pdf_to_markdown(pdf_content: bytes) -> str:
    try:
        await asyncio.wait_for(asyncio.sleep(100), timeout=settings.conversion_timeout)
    except asyncio.TimeoutError:
        raise TimeoutError("PDF conversion timed out")
    return "# Converted Markdown\n\nThis is simulated content."

async def store_result(doc_id: str, markdown_content: str):
    # Implement your storage logic here
    pass